#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
int main()
{
res_init();
int i = 0;
for (i = 0;i< _res.nscount;i++) /* _res.nscount为找到的域名服务器的数量 */
{
struct sockaddr_in addr = _res.nsaddr_list[i]; /* 域名服务器的地址 */
}
int class = C_IN;
int type = T_A;
unsigned char answer[512]="";
int n =res_query("www.baidu.com", class, type, answer, sizeof(answer)); /* answer中为域名解析的结果 */
res_close();
for(int i=0; i<n; i++){
printf("%02x", answer[i]);
}
}
这种方法由于使用到了静态全局变量 _res
,因此并不是线程安全的。为此glib提供了线程安全的对应函数 res_ninit
, res_nquery
, res_nclose
:
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
int main()
{
res_state res = malloc(sizeof(*res));
res_ninit(res);
int i = 0;
for (i = 0;i< res->nscount;i++) /* res->nscount存储了域名服务器的个数 */
{
struct sockaddr_in addr = res->nsaddr_list[i]; /* 域名服务器的地址 */
}
int class = C_IN;
int type = T_A;
unsigned char answer[256]="";
int n =res_nquery(res, "www.baidu.com", class, type, answer, sizeof(answer)); /* answer中为域名解析的结果 */
res_nclose(res);
for(int i=0; i<n; i++){
printf("%02x", answer[i]);
}
}
其中:
answer
中的结果是二进制格式的,不能直接解读。我们可以用python的 dnslib 库来帮忙解读import dnslib import binascii data=binascii.a2b_hex(answer) return dnslib.DNSRecord.parse(data)
res_state
的定义在 resolv/bits/types/res_state.h 中/* res_state: the global state used by the resolver stub. */ #define MAXNS 3 /* max # name servers we'll track */ #define MAXDFLSRCH 3 /* # default domain levels to try */ #define MAXDNSRCH 6 /* max # domains in search path */ #define MAXRESOLVSORT 10 /* number of net to sort on */ struct __res_state { int retrans; /* retransmition time interval */ int retry; /* number of times to retransmit */ unsigned long options; /* option flags - see below. */ int nscount; /* number of name servers */ struct sockaddr_in nsaddr_list[MAXNS]; /* address of name server */ unsigned short id; /* current message id */ /* 2 byte hole here. */ char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */ char defdname[256]; /* default domain (deprecated) */ unsigned long pfcode; /* RES_PRF_ flags - see below. */ unsigned ndots:4; /* threshold for initial abs. query */ unsigned nsort:4; /* number of elements in sort_list[] */ unsigned ipv6_unavail:1; /* connecting to IPv6 server failed */ unsigned unused:23; struct { struct in_addr addr; uint32_t mask; } sort_list[MAXRESOLVSORT]; /* 4 byte hole here on 64-bit architectures. */ void * __glibc_unused_qhook; void * __glibc_unused_rhook; int res_h_errno; /* last one set for this context */ int _vcsock; /* PRIVATE: for res_send VC i/o */ unsigned int _flags; /* PRIVATE: see below */ /* 4 byte hole here on 64-bit architectures. */ union { char pad[52]; /* On an i386 this means 512b total. */ struct { uint16_t nscount; uint16_t nsmap[MAXNS]; int nssocks[MAXNS]; uint16_t nscount6; uint16_t nsinit; struct sockaddr_in6 *nsaddrs[MAXNS]; #ifdef _LIBC unsigned long long int __glibc_extension_index __attribute__((packed)); #else unsigned int __glibc_reserved[2]; #endif } _ext; } _u; }; typedef struct __res_state *res_state;
class
和type
的定义在 resolv/arpa/nameser.h 中/*% * Values for class field */ typedef enum __ns_class { ns_c_invalid = 0, /*%< Cookie. */ ns_c_in = 1, /*%< Internet. */ ns_c_2 = 2, /*%< unallocated/unsupported. */ ns_c_chaos = 3, /*%< MIT Chaos-net. */ ns_c_hs = 4, /*%< MIT Hesiod. */ /* Query class values which do not appear in resource records */ ns_c_none = 254, /*%< for prereq. sections in update requests */ ns_c_any = 255, /*%< Wildcard match. */ ns_c_max = 65536 } ns_class; typedef enum __ns_type { ns_t_invalid = 0, ns_t_a = 1, ns_t_ns = 2, ns_t_md = 3, ns_t_mf = 4, ns_t_cname = 5, ns_t_soa = 6, ns_t_mb = 7, ns_t_mg = 8, ns_t_mr = 9, ns_t_null = 10, ns_t_wks = 11, ns_t_ptr = 12, ns_t_hinfo = 13, ns_t_minfo = 14, ns_t_mx = 15, ns_t_txt = 16, ns_t_rp = 17, ns_t_afsdb = 18, ns_t_x25 = 19, ns_t_isdn = 20, ns_t_rt = 21, ns_t_nsap = 22, ns_t_nsap_ptr = 23, ns_t_sig = 24, ns_t_key = 25, ns_t_px = 26, ns_t_gpos = 27, ns_t_aaaa = 28, ns_t_loc = 29, ns_t_nxt = 30, ns_t_eid = 31, ns_t_nimloc = 32, ns_t_srv = 33, ns_t_atma = 34, ns_t_naptr = 35, ns_t_kx = 36, ns_t_cert = 37, ns_t_a6 = 38, ns_t_dname = 39, ns_t_sink = 40, ns_t_opt = 41, ns_t_apl = 42, ns_t_ds = 43, ns_t_sshfp = 44, ns_t_ipseckey = 45, ns_t_rrsig = 46, ns_t_nsec = 47, ns_t_dnskey = 48, ns_t_dhcid = 49, ns_t_nsec3 = 50, ns_t_nsec3param = 51, ns_t_tlsa = 52, ns_t_smimea = 53, ns_t_hip = 55, ns_t_ninfo = 56, ns_t_rkey = 57, ns_t_talink = 58, ns_t_cds = 59, ns_t_cdnskey = 60, ns_t_openpgpkey = 61, ns_t_csync = 62, ns_t_spf = 99, ns_t_uinfo = 100, ns_t_uid = 101, ns_t_gid = 102, ns_t_unspec = 103, ns_t_nid = 104, ns_t_l32 = 105, ns_t_l64 = 106, ns_t_lp = 107, ns_t_eui48 = 108, ns_t_eui64 = 109, ns_t_tkey = 249, ns_t_tsig = 250, ns_t_ixfr = 251, ns_t_axfr = 252, ns_t_mailb = 253, ns_t_maila = 254, ns_t_any = 255, ns_t_uri = 256, ns_t_caa = 257, ns_t_avc = 258, ns_t_ta = 32768, ns_t_dlv = 32769, ns_t_max = 65536 } ns_type;
其他函数说明可以参见 man resolver
.